import { RightOutlined, InfoCircleOutlined } from '@ant-design/icons'
import AutoSizer from 'react-virtualized-auto-sizer'
import { FixedSizeList as List } from 'react-window'
import InfiniteLoader from 'react-window-infinite-loader'
import { Empty } from '@/desktop/components'
import  defaultAvatar  from '@/desktop/assets/avatar.jpg'
import type { ContactData, useSearchedContacts } from '@/desktop/logics/contacts-search'
import type { Contact } from '@/services/contacts'
import { ContactType } from '@/services/contacts'
import './contact-list.module.less'

type SearchedContacts = ReturnType<typeof useSearchedContacts>

export default function ContactList(props: {
  type: ContactType
  contacts: SearchedContacts['contacts']
  hasConditions: SearchedContacts['hasConditions']
  externalSearching: SearchedContacts['externalSearching']
  externalSearchNext: SearchedContacts['externalSearchNext']
  internalSearching: SearchedContacts['internalSearching']
  internalSearchNext: SearchedContacts['internalSearchNext']
  onClick: (contact: Contact) => void
}) {
  const {
    type,
    contacts,
    hasConditions,
    externalSearching,
    externalSearchNext,
    internalSearching,
    internalSearchNext,
    onClick: propsOnClick,
  } = props

  const loaderProps = useMemo(() => {
    // 只对客户和员工搜索，启用 InfiniteLoader
    if (type === ContactType.external && externalSearching) {
      const finish = 'finish' in externalSearching && externalSearching.finish
      return {
        isItemLoaded(index: number) {
          return finish || index < contacts.length
        },
        itemCount: !finish ? contacts.length + 1 : contacts.length,
        loadMoreItems: async () => externalSearchNext().then(() => {}),
      }
    } else if (type === ContactType.internal && internalSearching) {
      const finish = 'finish' in internalSearching && internalSearching.finish
      return {
        isItemLoaded(index: number) {
          return finish || index < contacts.length
        },
        itemCount: !finish ? contacts.length + 1 : contacts.length,
        loadMoreItems: async () => internalSearchNext().then(() => {}),
      }
    }
    return {
      isItemLoaded() {
        return true
      },
      loadMoreItems() {},
      itemCount: contacts.length,
    }
  }, [type, contacts, externalSearching, externalSearchNext, internalSearching, internalSearchNext])

  const onClick = useCallback(
    ({ contact }: ContactData) => {
      propsOnClick(contact)
    },
    [propsOnClick],
  )

  // 此函数每次重新生成，会导致列表里的元素都重新“生成“（不是重新渲染，是重新生成组件并挂载），因此尽量不要有依赖
  const Item = useCallback(
    ({
      data,
      index,
      style,
    }: {
      data: ContactData[]
      index: number
      style: React.CSSProperties
    }) => <ContactItem
      style={style}
      contactData={data[index]!}
      onClick={() => onClick(data[index]!)}
    />,
    [onClick],
  )
  const itemKey = useCallback((index: number, list: ContactData[]) => list[index]!.contact.id, [])

  return <div styleName="contacts">
    {!hasConditions ? (
      <div styleName="placeholder">
        <InfoCircleOutlined />
        请指定搜索条件
      </div>
    ) : null}

    {hasConditions && !contacts.length ? <Empty /> : null}

    {hasConditions && contacts.length ? (
      <AutoSizer>
        {({ width, height }) => <InfiniteLoader {...loaderProps}>
          {({ onItemsRendered, ref }) => <List
            ref={ref}
            onItemsRendered={onItemsRendered}
            height={height}
            width={width}
            itemCount={contacts.length}
            itemSize={79}
            itemData={contacts}
            itemKey={itemKey}
          >
            {Item}
          </List>}
        </InfiniteLoader>}
      </AutoSizer>
    ) : null}
  </div>
}

function ContactItem(props: {
  contactData: ContactData
  onClick: () => void
  style?: React.CSSProperties
}) {
  const {
    contactData: { contact, ownerName },
    onClick,
    style,
  } = props

  return <div style={style} styleName="contact" onClick={onClick}>
    <img styleName="avatar" loading="lazy" src={contact.avatar || defaultAvatar} />
    <div styleName="main">
      <div styleName="name">
        <span>
          {contact.remark ? (
            <>
              {contact.remark}
              <span styleName="tip-name">{contact.name}</span>
            </>
          ) : (
            contact.name
          )}
        </span>
      </div>
      <div styleName="owner-name">{ownerName}</div>
    </div>
    <div styleName="side">
      <RightOutlined />
    </div>
  </div>
}
